package com.jdjc.wx.controller;

import com.jdjc.wx.handler.WxChatMsgFactory;
import com.jdjc.wx.handler.WxChatMsgHandler;
import com.jdjc.wx.utils.MessageUtil;
import com.jdjc.wx.utils.SHA1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;

@RestController
@Slf4j
public class CallBackController {
    private static final String token = "mcw";


    @Resource
    private WxChatMsgFactory wxChatMsgFactory;

    @RequestMapping("/test")
    public String test() {
        return "你好";
    }

    /**
     * 回调消息校验
     *
     * @param signature 微信加密签名
     * @param timestamp 时间戳
     * @param nonce     随机数
     * @param echostr   随机字符串
     * @return
     */
    @GetMapping("/callback")
    public String callback(@RequestParam("signature") String signature,
                           @RequestParam("timestamp") String timestamp,
                           @RequestParam("nonce") String nonce,
                           @RequestParam("echostr") String echostr) {
        log.info("get验签请求参数，signature:{},timestamp:{},nonce:{},echostr:{}", signature, timestamp, nonce, echostr);
        //将三个参数字符串拼接成一个字符串进行sha1加密
        String shaStr = SHA1.getSHA1(token, timestamp, nonce, "");
        //3）开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
        if (signature.equals(shaStr)) {
            return echostr;
        }
        return "unknown";
    }

    @PostMapping(value = "/callback", produces = "application/xml;charset=UTF-8")
    public String callback(@RequestBody String requestBody,
                           @RequestParam("signature") String signature,
                           @RequestParam("timestamp") String timestamp,
                           @RequestParam("nonce") String nonce,
                           @RequestParam(value = "msg_signature", required = false) String msgSignature) {
        log.info("接收到微信的请求，requestBody:{},signature:{},timestamp:{},nonce:{},msg_signature:{}",
                requestBody, signature, timestamp, nonce, msgSignature);
        // 解析请求体中的XML数据，并将其转换为键值对形式存储在Map中
        Map<String, String> msgMap = MessageUtil.parseXml(requestBody);

        // 从msgMap中获取消息类型
        String msgType = msgMap.get("MsgType");

        // 尝试从msgMap中获取事件类型，如果不存在则默认为空字符串
        String event = msgMap.get("Event") == null ? "" : msgMap.get("Event");

        log.info("msgType:{},event:{}", msgType, event);

        // 创建一个StringBuilder对象，用于构建最终的消息类型键
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(msgType);

        // 如果事件类型不为空，则在消息类型后追加事件类型，构成复合键
        if (!StringUtils.isEmpty(event)) {
            stringBuilder.append(".");
            stringBuilder.append(event);
        }

        // 将构建好的字符串转换为字符串形式的消息类型键
        String msgTypeKey = stringBuilder.toString();

        // 根据消息类型键获取对应的处理器（工厂+策略）
        WxChatMsgHandler wxChatMsgHandler = wxChatMsgFactory.getHandlerByMsgType(msgTypeKey);

        if (Objects.isNull(wxChatMsgHandler)) {
            return "unknown";
        }

        // 使用处理器处理消息，并获取回复内容
        String replyContent = wxChatMsgHandler.dealMsg(msgMap);

        log.info("replyContent:{}", replyContent);

        return replyContent;
    }

}
